﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.IO;

namespace DynaSpace
{
	internal static class ComponentManager
	{
		/// <summary>
		/// Vrací všechny dll knihovny, které je možné načíst při inicializaci 
		/// </summary>
		/// <returns></returns>
		public static string[] GetAllFiles()
		{
			return System.IO.Directory.GetFiles(Application.StartupPath, "DynaSpace.*.dll");
		}

		/// <summary>
		/// Vrací všechny aktivní systémové pluginy + všechny pluginy z dll assembly.
		/// </summary>
		/// <param name="game">Hra, pro které se pluginy vytvářejí.</param>
		/// <param name="files">Soubory pluginů, které se mají načíst</param>
		/// <returns>Kolekce <see cref="DynaComponentBase"/>.</returns>
		public static List<DynaComponentBase> LoadComponents(DynaGame game, IEnumerable<string> files)
		{
			var retVal = new List<DynaComponentBase>();

			// načíst systémové komponenty
			retVal.AddRange(GetSystemComponents(game));

			Type componentBaseType = typeof(DynaComponentBase); // typ pluginu
			Type gameType = typeof(DynaGame); // typ hry (do parametru konstruktoru)

			foreach (string fileNamePath in files)
			{
				string fileName = Path.GetFullPath(fileNamePath);
		
				try
				{
					Assembly asm = Assembly.LoadFile(fileName);
					// projít všechny typy v assembly
					foreach (Type type in asm.GetTypes())
					{
						// vyhledat ty, které dědí z basePlugin
						if (componentBaseType.IsAssignableFrom(type))
						{
							// vytvořit z konstruktoru (s paremetrem DynaSpaceGame) instanci
							DynaComponentBase componentInstance = type.GetConstructor(new Type[] { gameType }).Invoke(new object[] { game }) as DynaComponentBase;

							// zjistit content folder a nastavit ji komponente
							string contentFolder = Path.Combine(Path.GetDirectoryName(fileName), "Content");
							componentInstance.ContentFolder = contentFolder;

							// přidat do seznamu instanci komponenty
							retVal.Add(componentInstance);
						}
					}
				}
				catch
				{
					// chyba načítání pluginu
				}
			}

			return retVal;
		}

		/// <summary>
		/// Vrací systémové pluginy
		/// </summary>
		private static IEnumerable<DynaComponentBase> GetSystemComponents(DynaGame game)
		{
			// systémové pluginy
			yield return new ContentComponent(game);
			yield return new MenuRendererComponent(game);
			yield return new LogoComponent(game);
		}
	}
}
